Immutable 中文意思為不可變的,
即重新賦值後,
新的值和原始的值並不互相影響
原本的值依然會保留下來,
不會被賦值改變。
Immutable 範例
let str = 'Hello, you!!';
let ianHello = str;
ianHello += 'ian';
// not changed
console.log(str); // Hello, you!!
console.log(ianHello); // Hello, you!!ian
與之相反的是 mutable,
第一次賦值後,
對物件進行如賦值等操作後,
mutable 的內容會產生變化。
Mutable 範例
let names = ['ian'];
let copyName = names;
copyName.push('peter');
// changed
console.log(names); // [ian, peter]
console.log(copyName); // [ian, peter]
而 React 為了避免資源浪費,
會比較元件的 props 和 state 是否有變更,
在無變化的情況下便不會觸發 re-render,
因此 state 更新的內容必須是 Immutable,
否則 React 就無法追蹤到資料內容的變化,
也就不會觸發任何 render。
無法觸發 re-render 的範例:
const [state, setState] = useState({
list: []
})
clickBtn = () => {
state.list.push({
id: Math.random(),
name: randomStr.generate(4)
});
setState(state);
};
如上方範例中,
直接修改 state 的 list 陣列內容,
但 state 本身在記憶體中
依然指向同樣的參考,
程式並未收到變更訊息,
所以不會觸發 render。
setState({
list: [
...state.list,
{ id: Math.random(), name: randomStr.genreate(4) }
]
});
把原本的 state 淺拷貝一份出來,
給予不同的記憶體位置後,
就可以正確 render 了。
使用 Object.assign 或是 es6 解構的時候只能對第一層拷貝,如果有多層資料時,裡面的東西就不會被拷貝到,依然是原本物件儲存的參考,這時一樣無法觸發 render。
const a = { b: { c: 1344 } };
const b = {...a);
b.b.c = 2000;
console.log(a.b.c) //2000
以下列出一些在改變 state 時,
能輕鬆達成 Immutable 的輔助套件。